﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Xml;
//MicroDesigner
using Jc.MicroDesigner.Events;
using Jc.MicroDesigner.Drawings;
using Jc.MicroDesigner.Management;

namespace Jc.MicroDesigner.Objects
{
    /// <summary>
    /// Элемент типа "узел"
    /// </summary>
    public sealed class Node : CircuitElement
    {
        private sealed class NodeImage : ElementImage
        {
            public NodeImage(Node parent)
                : base(parent)
            {
                this.onPaint += new onPaintElement(NodeImage_onPaint);
                this._Width = 5;
                this._Height = 5;
            }

            /// <summary>
            /// Отрисовка узла
            /// </summary>
            /// <param name="img"></param>
            /// <param name="element"></param>
            void NodeImage_onPaint(Image img, BaseElement element)
            {
                Graphics g = Graphics.FromImage(img);
                Brush br = new SolidBrush(Color.Black);
                g.FillRectangle(br, 0, 0, _Width, _Height);
                g.Dispose();
            }

            public override PIN GetBindingPIN(int x, int y)
            {
                (_Parent as Node).ClearUnusedPINs();
                PIN p = (_Parent as Node).CreateSpecialPIN();
                return p;
            }
        }

        /// <summary>
        /// Создать узел
        /// </summary>
        /// <param name="name"></param>
        public Node(string name)
            : base(name, 0)
        {
            this._DrawOptions = new NodeImage(this);
        }

        private void OnReceive(PIN sender)
        {
            for (int i = 0; i < _PINCollection.Count; i++)
            {
                if (_PINCollection[i] != sender)
                    _PINCollection[i].Send(sender.Signal);
            }
        }

        /// <summary>
        /// Метод для создания пинов узла
        /// </summary>
        /// <returns>Пин</returns>
        protected override PIN CreateSpecialPIN()
        {
            PIN pin = base.CreateSpecialPIN();
            (pin.DrawOptions as PIN.PINImage).BindingPoint = new Point(3, 3);
            pin.onRecieve += new onRecieveHandler(this.OnReceive);
            _PINCollection.Add(pin);
            return pin;
        }

        /// <summary>
        /// Добавить пин в узел
        /// </summary>
        /// <param name="pin">Пин провода</param>
        public void AddWire(PIN pin)
        {
            PIN a = CreateSpecialPIN();
            PIN.Unite(a, pin);
        }

        /// <summary>
        /// Удаляет PIN'ы у которых нет соединений
        /// </summary>
        public void ClearUnusedPINs()
        {
            for (int i = PINs.Count - 1; i >= 0; i--)
            {
                if (PINs[i].FriendPIN == null)
                    PINs.RemoveAt(i);
            }
        }

        /// <summary>
        /// Загрузить дополнительные свойства
        /// </summary>
        /// <param name="nodes">Ветви свойств</param>
        public override void LoadAdditionals(Dictionary<ConfigSection, XmlNode> nodes)
        {
            //Просто создать нужное количество пинов
            XmlNode pins = nodes[ConfigSection.Pins];
            int count = pins.ChildNodes.Count;
            for (int i = 0; i < count; i++)
                CreateSpecialPIN();
        }
    }
}